package br.xraylol.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import org.springframework.beans.factory.annotation.Autowired;

import br.xraylol.bean.riot.AggregatedStatsBean;
import br.xraylol.bean.riot.ChampionStatsBean;
import br.xraylol.bean.riot.LeagueBean;
import br.xraylol.bean.riot.LeagueItemBean;
import br.xraylol.bean.riot.PlayerStatsSummaryBean;
import br.xraylol.bean.riot.RankedStatsBean;
import br.xraylol.bean.riot.SummonerBean;
import br.xraylol.client.LeagueClient;
import br.xraylol.client.StatsClient;
import br.xraylol.client.SummonerClient;
import br.xraylol.constant.PlayerStatSummaryType;
import br.xraylol.custom.list.PlayerStatsSummaryList;

import com.fasterxml.jackson.databind.ObjectMapper;

@Path("/summoner")
public class SummonerService {
	
	@Autowired
	private SummonerClient summonerClient;
	
	@Autowired
	private StatsClient statsClient;
	
	@Autowired
	private LeagueClient leagueClient;
	
	@Autowired
	private ChampionService championService;
	
	@Autowired(required = true)
	private ObjectMapper objectMapper;
	
	/**
	 * Get detailed description of the player
	 * @param players
	 * @return Detailed description of the player
	 */
	@GET
	@Path("/{players}")
	public HashMap<String, String> getSummaryPlayers(@PathParam("players") HashMap<String, String> players) {
		HashMap<String, String> summaries = new HashMap<String, String>();
		List<String> summonersName = new ArrayList<String>(players.keySet());
		HashMap<String, SummonerBean> summoners = summonerClient.findSummonersByName(summonersName);
		
		StringBuilder description = null;
		String championName = null;

		for (Map.Entry<String, SummonerBean> summonerEntry : summoners.entrySet()) {
			description = new StringBuilder();
			SummonerBean summoner = objectMapper.convertValue(summonerEntry.getValue(), SummonerBean.class);
			for(Map.Entry<String, String> player : players.entrySet()) {
				String namePlayer = player.getKey();
				if (namePlayer.toUpperCase().equals(summoner.getName().toUpperCase())) {
					championName = player.getValue();
					break;
				}
				else
					championName = "";
			}
			
			description.append("Level: " + summoner.getSummonerLevel());
			description.append(System.lineSeparator());
			description.append(getTierLevel(summoner.getId()).toString());
			description.append(getDescriptionByChampion(summoner.getId(), championName).toString());
			description.append(getStatSummaryType(PlayerStatSummaryType.RankedSolo5x5, summoner.getId()));
			description.append(getStatSummaryType(PlayerStatSummaryType.Unranked, summoner.getId()));
			
			System.out.println(summoner.getName());
			System.out.println(description.toString().trim());
			System.out.println("-------------------------------");
			summaries.put(summoner.getName(), description.toString().trim());
		}
		
		return players;
	}
	
	private StringBuilder getStatSummaryType(PlayerStatSummaryType playerStat, Long summonerId) {
		StringBuilder description = new StringBuilder();
		PlayerStatsSummaryList playersStats = statsClient.findSummariesStats(summonerId);
		
		if (playersStats != null) {
			for (PlayerStatsSummaryBean playerStatsSummary : playersStats.getPlayerStatSummaries()) {
				if (playerStat.name().equals(playerStatsSummary.getPlayerStatSummaryType())) {
					Integer gamesPlayed = 0;
					Integer won = playerStatsSummary.getWins();
					Integer lost = playerStatsSummary.getLosses();
					description.append(playerStat.name());
					description.append(System.lineSeparator());
					
					if (won != null && won > 0) {
						description.append("Won:" + won);
						description.append(System.lineSeparator());
						gamesPlayed += playerStatsSummary.getWins();
					}
					
					if (lost != null && lost > 0) {
						description.append("Lost:" + lost);
						description.append(System.lineSeparator());
						gamesPlayed += playerStatsSummary.getLosses();
					}
					
					if (won == null || (won != null && won <= 0) ||
							lost == null || (lost != null && lost== 0)) {
						gamesPlayed = 0;
					}
					
					if (playerStatsSummary.getAggregatedStats() != null) {
						AggregatedStatsBean aggregatedStats = playerStatsSummary.getAggregatedStats();
						
						if (aggregatedStats.getTotalChampionKills() > 0) {
							Integer championKills = aggregatedStats.getTotalChampionKills();
							Integer assists = aggregatedStats.getTotalAssists();
							Integer minionKills = aggregatedStats.getTotalMinionKills();
							Integer neutralMinionKills = aggregatedStats.getTotalNeutralMinionsKilled();
							
							if (championKills != null && championKills > 0) {
								description.append("Kills: " + championKills + (gamesPlayed == 0 ? "" : " (" + championKills / gamesPlayed + "/game)"));
								description.append(System.lineSeparator());
							}
							
							if (assists != null && assists > 0) {
								description.append("Assists: " + assists + (gamesPlayed == 0 ? "" : " (" + assists / gamesPlayed + "/game)"));
								description.append(System.lineSeparator());
							}
							
							if (minionKills != null && minionKills > 0) {
								description.append("Minion kills: " + minionKills + (gamesPlayed == 0 ? "" : " (" + minionKills / gamesPlayed + "/game)"));
								description.append(System.lineSeparator());
							}
							
							if (neutralMinionKills != null && neutralMinionKills > 0) {
								description.append("Neutral minion kills: " + neutralMinionKills + (gamesPlayed == 0 ? "" : " (" + neutralMinionKills / gamesPlayed + "/game)"));
								description.append(System.lineSeparator());
							}
						}
					}
					description.append(System.lineSeparator());
					break;
				}
			}
		}

		return description;
	}
	
	private StringBuilder getTierLevel(Long summonerId) {
		StringBuilder description = new StringBuilder();
		ArrayList<LeagueBean> leaguesBySummoner = leagueClient.findLeaguesBySummoner(summonerId);
		String tier = null;

		if (leaguesBySummoner != null) {
			if (leaguesBySummoner.size() > 0) {
				LeagueBean leagueBean = objectMapper.convertValue(leaguesBySummoner.get(0), LeagueBean.class);
				for (LeagueItemBean leagueItem : leagueBean.getEntries()) {
					if (leagueItem.getPlayerOrTeamId().equals(summonerId.toString())) {
						tier = leagueItem.getTier() + " " + leagueItem.getRank();
						break;
					}
				}
			}
			 
			if (tier != null && !tier.isEmpty()) {
				description.append("Tier: " + tier);
				description.append(System.lineSeparator());
			}
		}
		else {
			description.append("Tier: UNRANKED");
			description.append(System.lineSeparator());
		}
		
		description.append(System.lineSeparator());
		
		return description;
	}
	
	private StringBuilder getDescriptionByChampion(Long summonerId, String championName) {
		RankedStatsBean rankedStats = statsClient.findRankedStats(summonerId);
		StringBuilder description = new StringBuilder();
		Integer championId = null;
		
		if (rankedStats != null) {
			if (!championName.isEmpty()) {
				championId = championService.findIdByName(championName);
				
				for (ChampionStatsBean championStats : rankedStats.getChampions()) {
					if (championId.equals(championStats.getId())) {
						description.append("Champion: " + championName + " ");
						
						if (championStats.getStats().getTotalPentaKills() > 0) {
							description.append("Pentakill");
						}
						else if (championStats.getStats().getTotalQuadraKills() > 0) {
							description.append("Quadrakill");
						}
						else if (championStats.getStats().getTotalTripleKills() > 0) {
							description.append("Triplekill");
						}
						else if (championStats.getStats().getTotalDoubleKills() > 0) {
							description.append("Doublekill");
						}
						
						if (championStats.getStats() != null) {
							AggregatedStatsBean stats = championStats.getStats();
							Integer gamesPlayed = stats.getTotalSessionsPlayed();
							Integer championKills = stats.getTotalChampionKills();
							Integer deaths = stats.getTotalDeathsPerSession();
							Integer assists = stats.getTotalAssists();
							Integer minionKills = stats.getTotalMinionKills();
							
							description.append(System.lineSeparator());
							description.append("Games played: " + gamesPlayed);
							description.append(System.lineSeparator());
							
							if (stats.getTotalSessionsWon() != null && stats.getTotalSessionsWon() > 0) {
								description.append("Won: " + championStats.getStats().getTotalSessionsWon());
								description.append(System.lineSeparator());
							}
							
							if (stats.getTotalSessionsLost() != null && stats.getTotalSessionsLost() > 0) {
								description.append("Lost: " + championStats.getStats().getTotalSessionsLost());
								description.append(System.lineSeparator());
							}
							
							if (championKills != null && championKills > 0) {
								description.append("Kills: " + championKills + " (" + championKills / gamesPlayed + "/game)");
								description.append(System.lineSeparator());
							}
							
							if (deaths != null && deaths > 0) {
								description.append("Deaths: " + deaths + " (" + deaths / gamesPlayed + "/game)");
								description.append(System.lineSeparator());
							}
							
							if (assists != null && assists > 0) {
								description.append("Assists: " + assists + " (" + assists / gamesPlayed + "/game)");
								description.append(System.lineSeparator());
							}
							
							if (minionKills != null && minionKills > 0) {
								description.append("Minion kills: " + minionKills + " (" + minionKills / gamesPlayed + "/game)");
								description.append(System.lineSeparator());
							}
						}
						description.append(System.lineSeparator());
						break;
					}
				}
			}
		}

		return description;
	}
}
